<template>
  <div class="common-form">
    <el-form inline size="small">
      <el-row>
        <div v-for="(item, index) in formJson">
          <el-form-item :label="item.label" :key="index" v-show="index < displayCount">
            <component :name="item.filed" :mini="mini" :ref="'component' + index" :is="'hl-' + item.type"
                       :options="item.options"
                       :query="typeof item.query === 'function' ? item.query(formModal) : item.query"
                       :isNotInCommonForm="false" :clearable="item.clearable !== false" :placeholder="item.placeholder"
                       :startPlaceholder="item.startPlaceholder" :endPlaceholder="item.endPlaceholder"
                       v-model="formModal[item.filed]" v-bind="item" />
          </el-form-item>
        </div>
        <slot />
        <el-form-item v-if="componentLoaded">
          <el-button size="small" icon="el-icon-search" type="primary" @click="search(1)" class="search-btn radiusbtn" />
          <el-button v-if="formJson.length && needReset" size="small" type="primary" plain class="radiusbtn"
                     @click="reset">重置</el-button>
          <el-button v-if="formJson.length > 4" type="text" @click="fold">{{ folding ? "展开" : "收起" }}</el-button>
        </el-form-item>
      </el-row>
    </el-form>
    <!-- {{formModal}} -->
  </div>
</template>

<script type="ts">
import { clickSec } from "@/utils/utils"
export default {
  name: "CommonForm",
  props: {
    formJson: {
      type: Array
    },
    mini: {
      type: Boolean,
      default: false
    },
    autoSearch: {
      type: Boolean,
      default: true
    },
    needReset: {
      type: Boolean,
      default: true
    }
  },
  components: {
    "hl-input": lazyLoadComponent("Input"),
    "hl-select": lazyLoadComponent("Select"),
    "hl-datepicker": lazyLoadComponent("DatePicker"),
    "hl-datesinglepicker": lazyLoadComponent("DateSinglePicker"),
    "hl-cascader": lazyLoadComponent("Cascader"),
    "hl-selectremote": lazyLoadComponent("SelectRemote"),
    "hl-address": lazyLoadComponent("Address"),
    "hl-productSelect": lazyLoadComponent("ProductSelect")
  },
  data() {
    return {
      formModal: getQueryParams(this.formJson),
      folding: true,
      displayCount: 4,
      componentLoaded: false
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.componentLoaded = true
      this.autoSearch && this.search()
    })
  },
  methods: {
    // 通过ref设置查询条件
    setOption(key, value) {
      this.formModal[key] = value
    },
    // 刷新下拉框查询条件
    refresh() {
      for (let i = 0; i < this.formJson.length; i++) {
        // refs 是个数组?
        if (this.$refs["component" + i][0].queryOption) {
          this.$refs["component" + i][0].queryOption()
        }
      }
    },
    // 重置参数
    reset() {
      this.formModal = getQueryParams(this.formJson)
      if ("zone" in this.formModal) {
        for (let i = 0; i < this.formJson.length; i++) {
          // refs 是个数组?
          if (this.$refs["component" + i][0].setArea) {
            this.$refs["component" + i][0].setArea(["", "", ""])
          }
        }
      }
      this.$emit("reset")
      this.search()
    },
    fold() {
      this.folding = !this.folding
      this.displayCount = this.displayCount === 100 ? 4 : 100
    },
    search(e) {
      if (e) {
        if (this.searchTime && new Date() - this.searchTime < this.$clickSec) {
          this.$message.error(`不要点击太快哦`)

          return
        }
        this.searchTime = new Date()
      }
      const keys = Object.keys(this.formModal)
      const result = {}
      keys.forEach((key) => {
        if (key.indexOf("daterange") > -1) {
          /*
           * 自定义日期范围字段
           * ...
           * filed: 'daterange',
           * params: {
           *   start: 'startTime',
           *   end: 'endTime',
           * }
           * ...
           */

          const temp = this.formJson.filter((el) => el.filed == key)[0]
          const startTime = (temp && temp.params && temp.params.start) || "startTime"
          const endTime = (temp && temp.params && temp.params.end) || "endTime"
          result[startTime] = this.formModal[key][0] || ""
          result[endTime] = this.formModal[key][1] || ""
        } else if (key === "zone") {
          /*
           * 自定义地区字段
           * ...
           * filed: 'zone',
           * params: {
           *   country: 'country',
           *   province: 'province',
           *   city: 'city',
           *   region: 'region',
           * }
           * ...
           */

          const temp = this.formJson.filter((el) => el.filed == key)[0]
          // let country = (temp && temp.params && temp.params.country) || 'country'
          const province = (temp && temp.params && temp.params.province) || "province"
          const city = (temp && temp.params && temp.params.city) || "city"
          const region = (temp && temp.params && temp.params.region) || "region"
          // result[country] = this.formModal[key][0] || ''
          result[province] = this.formModal[key][0] || ""
          result[city] = this.formModal[key][1] || ""
          result[region] = this.formModal[key][2] || ""
        } else if (key == "product_model") {
          const temp = this.formJson.filter((el) => el.filed == key)[0]
          const series = (temp && temp.params && temp.params.series) || "series"
          const model = (temp && temp.params && temp.params.model) || "model"
          result[series] = this.formModal[key][0] || ""
          result[model] = this.formModal[key][1] || ""
        } else {
          result[key] = this.formModal[key]
        }
      })
      this.searchPms = result
      this.$emit("search", result)
    }
  }
}
function lazyLoadComponent(componentPath) {
  return () => import(`./${componentPath}`)
}
function getQueryParams(json) {
  const obj = {}
  json.forEach((el) => {
    obj[el.filed] = el.default
  })
  return obj
}
</script>
<style lang="less">
.common-form {
  .el-form-item {
    margin-bottom: 8px;
    margin-right: 8px;
  }

  .search-btn.el-button--small {
    font-size: 14px;
    padding: 8px;
  }

  .el-button+.el-button {
    margin-left: 8px;
  }
}
</style>
